package com.lmx.web.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.GenerateQrCodeUtil;
import com.lmx.common.util.HttpRequestUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.common.util.XMLUtil;
import com.lmx.persistence.service.MessageService;
import com.lmx.persistence.service.PayRecordService;
import com.lmx.repoDomain.tmodel.Wechat;


/*-
 * 支付处理接口
 */

@Controller
@RequestMapping("/pay")
public class PaymentController {
    private static Log logger = LogFactory.getLog(PaymentController.class);
    @Autowired
    private PayRecordService payRecordService;
    @Autowired
    private MessageService messageService;


    @RequestMapping("/notify")
    @ResponseBody
    public void payNotify(HttpServletRequest request) {
        logger.debug("-----------------------------payment 微信支付返回-------------------------------------");
        BufferedReader in = null;
        String result = "";
        try{

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(request.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            logger.debug("payment : " + result);
        }catch (Exception e){
            logger.debug("payment : " +e.toString());
        }finally {
            try{
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        SortedMap map = payRecordService.XmlToSortedMap(result);
        //签名验证
        if(!payRecordService.verifySign(map)){
            logger.debug("微信支付返回签名错误");
            return;
        }
        payRecordService.rechargeAffirm(map);


    }

    @RequestMapping("/bind")
    public String bind(HttpServletRequest request,ModelMap model) {
        String state = request.getParameter("state");
        logger.debug("bind state:" + state);
        String code = request.getParameter("code");
        logger.debug("bind code:" + code);
        String nickname = "";
        Wechat wechat = null;
        if(StringUtils.isNotBlank(code)){
            wechat = payRecordService.bindWechat(code,state);
            nickname = wechat.getNickname();
        }
        if (wechat == null){
            logger.debug("-----------------------------bind绑定微信账号失败-------------------------------------");
            return "绑定微信账号失败";
        }
        model.put("nickname",nickname);
        logger.debug("-----------------------------bind绑定微信账号成功:" + nickname + "-------------------------------------");
        return "page/wechat/bindSucc";
    }

    /**
     * 扫码支付  充值
     */
    public  void test(){
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
        String appid = properties.getProperty("weixin.appid");
        String mch_id = properties.getProperty("weixin.mch_id");
        String device_info = properties.getProperty("weixin.device_info");
        String key = properties.getProperty("weixin.key");
        String unifiedorderURL = properties.getProperty("weixin.url.unifiedorder");
        String notify_url = properties.getProperty("weixin.notify_url")  + "/pay/notify";//回调地址
        String nonce_str = CommonUtil.createNonceStr(); //随机字符串
        String body = "呼叫云充值";//商品描述
        String totalFee = "1"; //金额必须为整数  单位为分
        String productId = CommonUtil.createNonceStr(); // 商户根据自己业务传递的参数 必填
        String tradeNo = CommonUtil.createNonceStr();//商户 后台的贸易单号

        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        parameters.put("appid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("device_info", device_info);
        parameters.put("body", body);
        parameters.put("nonce_str", nonce_str);
        parameters.put("trade_type", "NATIVE"); //交易类型
        parameters.put("spbill_create_ip",localIp()); //本机的Ip
        parameters.put("product_id", productId); // 商户根据自己业务传递的参数 必填
        parameters.put("out_trade_no", tradeNo); //商户 后台的贸易单号
        parameters.put("total_fee", totalFee); //金额必须为整数  单位为分
        parameters.put("notify_url", notify_url); //支付成功后，回调地址
//        parameters.put("key", key);
        parameters.put("sign",createSign(key,parameters));
//        Map<Object,Object> map = new HashMap<>();
//        map.put("sign",createSign(key,parameters));//根据微信签名规则，生成签名
        String xmlData = XMLUtil.converter(parameters) ;
/*        xmlData = "<xml>\n" +
                "<appid>wxee49ccab3c103231</appid>\n" +
                "<body>pay</body>\n" +
                "<device_info>WEB</device_info>\n" +
                "<mch_id>1369886402</mch_id>\n" +
                "<nonce_str>af8d1eb220186400c494db7091e402b0</nonce_str>\n" +
                "<notify_url>http://loaclhost:8081/pay/notify</notify_url>\n" +
                "<out_trade_no>321</out_trade_no>\n" +
                "<product_id>123</product_id>\n" +
                "<spbill_create_ip>10.2.2.75</spbill_create_ip>\n" +
                "<total_fee>1000</total_fee>\n" +
                "<trade_type>NATIVE</trade_type>\n" +
                "<sign>DADC6E00FA2128E8231DBF124C9571F2</sign>\n" +
                "</xml>";*/
 /*       xmlData = "<xml>\n" +
                "<appid>wxd930ea5d5a258f4f</appid>\n" +
                "<mch_id>10000100</mch_id>\n" +
                "<device_info>1000<device_info>\n" +
                "<body>test</body>\n" +
                "<nonce_str>ibuaiVcKdpRxkhJA</nonce_str>\n" +
                "<sign>9A0A8659F005D6984697E2CA0A9CF3B7</sign>\n" +
                "<xml>";*/
        System.out.println(xmlData);
        String resXml = HttpRequestUtil.postData(unifiedorderURL, xmlData);
        System.out.println(resXml);
        Document dd = null;
        String code_url=null;
        try {
            dd = DocumentHelper.parseText(resXml);
        } catch (DocumentException e) {
            logger.debug(e.toString());
        }
        if (dd != null) {
            Element root = dd.getRootElement();
            if (root == null) {
                return;
            }
            Element codeUrl = root.element("code_url");
            if (codeUrl == null) {
                return;
            }
            code_url = codeUrl.getText();  //解析 xml 获得 code_url
        }
        logger.debug(code_url);
        GenerateQrCodeUtil.generateQrcode(code_url);
       /* HashMap<String, String> paramMap = Maps.newHashMap();
        paramMap.put("trade_type", "NATIVE"); //交易类型
        paramMap.put("spbill_create_ip",localIp()); //本机的Ip
        paramMap.put("product_id", "payOrderIdsStr"); // 商户根据自己业务传递的参数 必填
        paramMap.put("body", "orderSubject");         //描述
        paramMap.put("out_trade_no", "payOrderIdsStr"); //商户 后台的贸易单号
        paramMap.put("total_fee", "" + "totalCount"); //金额必须为整数  单位为分
        paramMap.put("notify_url", "http://" + getAccessDomain() + "/wx_pay_notify"); //支付成功后，回调地址
        paramMap.put("appid", siteConfig.getWxPayAppId()); //appid
        paramMap.put("mch_id", siteConfig.getWxPayMchId()); //商户号
        paramMap.put("nonce_str", CommonUtilPub.createNoncestr(32));  //随机数
        paramMap.put("sign",CommonUtilPub.getSign(paramMap,siteConfig.getWxPayPartnerKey()));//根据微信签名规则，生成签名
        String xmlData = CommonUtilPub.mapToXml(paramMap);//把参数转换成XML数据格式*/
    }

    /**
     * 获取本机Ip
     *
     *  通过 获取系统所有的networkInterface网络接口 然后遍历 每个网络下的InterfaceAddress组。
     *  获得符合 <code>InetAddress instanceof Inet4Address</code> 条件的一个IpV4地址
     * @return
     */
    private String localIp(){
        String ip = null;
        Enumeration allNetInterfaces;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                List<InterfaceAddress> InterfaceAddress = netInterface.getInterfaceAddresses();
                for (InterfaceAddress add : InterfaceAddress) {
                    InetAddress Ip = add.getAddress();
                    if (Ip != null && Ip instanceof Inet4Address) {
                        ip = Ip.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            logger.warn("获取本机Ip失败:异常信息:"+e.getMessage());
        }
        return ip;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        PaymentController paymentController = new PaymentController();
        paymentController.test2(); //001g4yte00N9mF1yQUwe0N0Cte0g4yt5
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxee49ccab3c103231&secret=77993ceae7240d21415deac5f3c207f8&code=001g4yte00N9mF1yQUwe0N0Cte0g4yt5&grant_type=authorization_code
//        https://api.weixin.qq.com/sns/userinfo?access_token=losnWS_P3VyIHBX5K9m8ONDvgwgJAqViUQBtRQBEdO95jDfkZ6bMTHmHO-JHN2rmc3D_HcD8y4W5bQ9bzVqcrCp-55qnpivgDy3jf-UEoDo&openid=oHvEzwvUshXWMHSAN0cFULxt3iho&lang=zh_CN
        GenerateQrCodeUtil.generateQrcode("https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxee49ccab3c103231&redirect_uri=http%3a%2f%2fapi.callcloud.com.cn%2fpay%2fbind&response_type=code&scope=snsapi_userinfo&state=byHand#wechat_redirect");
        if(true) return;
        System.out.println(">>>模拟微信支付<<<");
        System.out.println("==========华丽的分隔符==========");
        //微信api提供的参数
        String appid = "wxd930ea5d5a258f4f";
        String mch_id = "10000100";
        String device_info = "1000";
        String body = "test";
        String nonce_str = "ibuaiVcKdpRxkhJA";

        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        parameters.put("appid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("device_info", device_info);
        parameters.put("body", body);
        parameters.put("nonce_str", nonce_str);

        System.out.println(XMLUtil.converter(parameters));
        String characterEncoding = "UTF-8";
        String weixinApiSign = "9A0A8659F005D6984697E2CA0A9CF3B7";
        System.out.println("微信的签名是：" + weixinApiSign);
        String mySign = createSign(characterEncoding,parameters);
        System.out.println("我     的签名是："+mySign);

        if(weixinApiSign.equals(mySign)){
            System.out.println("恭喜你成功了~");
        }else{
            System.out.println("注定了你是个失败者~");
        }

        String userAgent = "Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X) AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206 MicroMessenger/5.0";

        char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger")+15);

        System.out.println("微信的版本号："+new String(new char[]{agent}));
    }

    /**
     * 微信支付签名算法sign
     * @param parameters
     * @return
     */
    public static String createSign(String key,SortedMap<Object,Object> parameters){
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
//        key = "192006250b4c09247ec02edce69f6a2d";//debugTest
        sb.append("key=" + key);
        System.out.println(sb);
        String sign = CommonUtil.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }

    /**
     * 提现（企业打款）
     */
    public  void test2(){
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
        String appid = properties.getProperty("weixin.appid");
        String mch_id = properties.getProperty("weixin.mch_id");
        String key = properties.getProperty("weixin.key");
        String transfersUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
        String nonce_str = CommonUtil.createNonceStr(); //随机字符串
        String partner_trade_no = CommonUtil.getCurrTimes() + "";//商户订单号
        String openid = "oHvEzwmRekARoorXgURpTh4zEhH0";//oHvEzwmRekARoorXgURpTh4zEhH0//oHvEzwvUshXWMHSAN0cFULxt3iho

        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        parameters.put("mch_appid", appid);
        parameters.put("mchid", mch_id);
        parameters.put("partner_trade_no", partner_trade_no); //商户订单号
        parameters.put("openid", openid);
        parameters.put("nonce_str", nonce_str);
        parameters.put("check_name", "NO_CHECK");
//        parameters.put("re_user_name", "3213");
        parameters.put("amount", "100");//金额必须为整数  单位为分
        parameters.put("desc", "提现");
        parameters.put("spbill_create_ip",localIp()); //本机的Ip

        parameters.put("sign",createSign(key,parameters));
        String xmlData = XMLUtil.converter(parameters) ;
        logger.debug("xmlData : " + xmlData);

        String resXml = HttpRequestUtil.postDataSSL(transfersUrl, xmlData);
        logger.debug("resXml ： " + resXml);

        Document dd = null;
        String resCode=null;
        try {
            dd = DocumentHelper.parseText(resXml);
        } catch (DocumentException e) {
            logger.debug(e.toString());
        }
        if (dd != null) {
            Element root = dd.getRootElement();
            if (root == null) {
                return ;
            }
            Element result = root.element("return_code");
            if (result == null) {
                return ;
            }
            resCode = result.getText();  //解析 xml 获得 resCode
        }
        logger.debug("resCode:" + resCode);
        if("SUCCESS".equals(resCode)){
           logger.debug("大人，真乃神人也");
        }
    }

    /**
     * 提现（红包）
     */
    public  void test3(){
        Properties properties = PropertiesFileUtil.getProperties("application.properties");
        String appid = properties.getProperty("weixin.appid");
        String mch_id = properties.getProperty("weixin.mch_id");
        String device_info = properties.getProperty("weixin.device_info");
        String key = properties.getProperty("weixin.key");
        String nonce_str = CommonUtil.createNonceStr(); //随机字符串
        String mch_billno = mch_id + "20160913" + "1234567895";//商户订单号
//        mch_billno = "1369886402201411111234567890";
        String openid = "oHvEzwhv-3AUZPsMxL8yyG2-4p2Y";//oHvEzwmRekARoorXgURpTh4zEhH0//oHvEzwvUshXWMHSAN0cFULxt3iho
        String sendredpackUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";

        SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
        parameters.put("wxappid", appid);
        parameters.put("mch_id", mch_id);
        parameters.put("send_name", "呼叫云");//商户名称
        parameters.put("mch_billno", mch_billno); //商户订单号
        parameters.put("re_openid", openid);
        parameters.put("nonce_str", nonce_str);
//        parameters.put("check_name", "NO_CHECK");
//        parameters.put("re_user_name", "3213");
        parameters.put("total_amount", "4480");//金额必须为整数  单位为分
        parameters.put("total_num", "1");//提现人数
        parameters.put("wishing", "邀约佣金");//红包祝福语
        parameters.put("act_name", "提现");//活动名称
        parameters.put("remark", "呼叫云提现红包");
        parameters.put("client_ip",localIp()); //本机的Ip

        parameters.put("sign",createSign(key,parameters));
        String xmlData = XMLUtil.converter(parameters) ;
        System.out.println(xmlData);

        String resXml = HttpRequestUtil.postDataSSL(sendredpackUrl, xmlData);
        System.out.println(resXml);
    }



}
